#include <Wire.h>
#include <Ticker.h>
#include "RTClib.h"

//IV18引脚定义
#define CLK   12
#define DIN   13
#define STO   14
#define BLANK 16

#define APPTIME     1
#define APPCPUSTATE 2
#define APPGPUSTATE 3

Ticker myget;   //环境参数时间获取

RTC_DS3231 rtc; //RTC实例化

String comdata = "";  //接收PC端指令
unsigned char APPMODE = 1;
unsigned int appmodecounter = 0;

int tempge=0,tempshi=0,tempbai=0;

unsigned char reflashram[9] = {'-', '-', '-', '-', '-', '-', '-', '-', '-'};
//unsigned char zihua=0;

unsigned int pIV18wei[9][9] = {{1, 0, 0, 0, 0, 0, 0, 0, 0}, //0
  {0, 0, 0, 0, 0, 0, 0, 0, 1}, //1
  {0, 0, 0, 0, 0, 0, 0, 1, 0}, //2
  {0, 0, 0, 0, 0, 0, 1, 0, 0}, //3
  {0, 0, 0, 0, 0, 1, 0, 0, 0}, //4
  {0, 0, 0, 0, 1, 0, 0, 0, 0}, //5
  {0, 0, 0, 1, 0, 0, 0, 0, 0}, //6
  {0, 0, 1, 0, 0, 0, 0, 0, 0}, //7
  {0, 1, 0, 0, 0, 0, 0, 0, 0}
}; //8
unsigned int pIV18zihua[11][8][8] = {{{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 1, 1, 1, 1, 1}, {0, 0, 1, 1, 1, 1, 1, 1}, {0, 0, 1, 1, 1, 1, 1, 1}}, //0 7
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}}, //1 3
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 1, 0, 0, 0, 0, 1, 1}, {0, 1, 0, 1, 0, 0, 1, 1}, {0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 1, 0, 1, 1}}, //2 6
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 1, 1, 1, 1}}, //3 6
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 1, 0, 0, 1, 1, 0}}, //4 5
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 1, 0, 1}, {0, 1, 1, 0, 1, 1, 0, 1}, {0, 1, 1, 0, 1, 1, 0, 1}, {0, 1, 1, 0, 1, 1, 0, 1}}, //5 6
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 1, 0, 0, 0, 0, 1}, {0, 0, 1, 1, 0, 0, 0, 1}, {0, 0, 1, 1, 1, 0, 0, 1}, {0, 0, 1, 1, 1, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 0, 1}}, //6 7
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}}, //7 4
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 1, 1, 1, 1, 1}, {0, 0, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1}}, //8 8
  {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 1, 1}, {0, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 0, 1, 1, 1, 1}, {0, 1, 1, 0, 1, 1, 1, 1}}, //9 6
  {{0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}}
};     //- //h,g,f,e,d,c,b,a
unsigned int pIV18zi[18][8] = { {0, 0, 1, 1, 1, 1, 1, 1}, //0
                                {0, 0, 0, 0, 0, 1, 1, 0}, //1
                                {0, 1, 0, 1, 1, 0, 1, 1}, //2
                                {0, 1, 0, 0, 1, 1, 1, 1}, //3
                                {0, 1, 1, 0, 0, 1, 1, 0}, //4
                                {0, 1, 1, 0, 1, 1, 0, 1}, //5
                                {0, 1, 1, 1, 1, 1, 0, 1}, //6
                                {0, 0, 0, 0, 0, 1, 1, 1}, //7
                                {0, 1, 1, 1, 1, 1, 1, 1}, //8
                                {0, 1, 1, 0, 1, 1, 1, 1}, //9
                                {0, 1, 0, 0, 0, 0, 0, 0}, //10 -
                                {1, 0, 0, 0, 0, 0, 0, 0}, //11 O大圆点
                                {1, 1, 0, 0, 0, 0, 0, 0}, //12 大圆点+横线
                                {0, 0, 0, 0, 0, 0, 0, 0}, //13
                                {0, 0, 1, 1, 1, 0, 0, 1}, //14 C
                                {0, 1, 1, 1, 0, 0, 1, 1}, //15 P
                                {0, 0, 1, 1, 1, 1, 1, 0}, //16 U
                                {0, 1, 1, 0, 1, 1, 1, 1}  //17 G
};

int second = 0, minute = 0, hour = 0;

void gettempandhum()
{
  DateTime now = rtc.now();
  hour = now.hour();
  minute = now.minute();
  second = now.second();

  /************************APP模式切换************************/
  appmodecounter++;
  
  if ((appmodecounter >= 600)&&(Serial.available() > 0))
  {
    APPMODE++;
    appmodecounter=0;
    if (APPMODE == 4)APPMODE = 1;
  }
  if(appmodecounter >= 3000)
  {
    appmodecounter=3010;
    APPMODE=1;
  }

  //    zihua++;
  //    if(zihua==8)zihua=0;
  //    Serial.print("Temperature: ");
  //    Serial.print(rtc.getTemperature());
  //    Serial.println(" C");
}

//IV18初始化
void iv18_init(void)
{
  pinMode(CLK, 1);
  pinMode(DIN, 1);
  pinMode(BLANK, 1);
  pinMode(STO, 1);

  digitalWrite(CLK, 0);
  digitalWrite(DIN, 0);
  digitalWrite(STO, 0);
  digitalWrite(BLANK, 0);
}

//IV18刷新显存
void iv18_reflash(unsigned char *reflashram)
{
  for (int i = 0; i < 8; i++)
  {
    if (*(reflashram + i) == '|') {*(reflashram + i) = 13;}
    if (*(reflashram + i) == '-') {*(reflashram + i) = 10;}
    if (*(reflashram + i) == 'C') {*(reflashram + i) = 14;}//C
    if (*(reflashram + i) == 'P') {*(reflashram + i) = 15;}//P
    if (*(reflashram + i) == 'U') {*(reflashram + i) = 16;}//U
    if (*(reflashram + i) == 'G') {*(reflashram + i) = 17;}//G
  }
  if (*(reflashram + 8) == '-') {*(reflashram + 8) = 10;}
  if (*(reflashram + 8) == '.') {*(reflashram + 8) = 11;}
  if (*(reflashram + 8) == '/') {*(reflashram + 8) = 12;}
  if (*(reflashram + 8) == '|') {*(reflashram + 8) = 13;}

  for (int wei = 0; wei < 9; wei++) //位刷新变量
  {
    for (int i = 0; i < 4; i++)
    {
      digitalWrite(CLK, 0);
      digitalWrite(DIN, 0);
      digitalWrite(CLK, 1);
    }

    for (int i = 0; i < 9; i++)
    {
      digitalWrite(CLK, 0);
      digitalWrite(DIN, pIV18wei[wei][i]);
      digitalWrite(CLK, 1);
    }
    for (int i = 0; i < 8; i++)
    {
      digitalWrite(CLK, 0);
      digitalWrite(DIN, pIV18zi[*(reflashram + wei)][i]); //显存池
      digitalWrite(CLK, 1);
    }
    digitalWrite(STO, 0);
    digitalWrite(STO, 1);
    digitalWrite(STO, 0);
    digitalWrite(BLANK, 0);
    digitalWrite(BLANK, 1);
    digitalWrite(BLANK, 0);
  }
}

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  iv18_init();

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  myget.attach(0.1, gettempandhum);
}

void loop()
{
  switch (APPMODE)
  {
    case (APPTIME) : {
        
        reflashram[8] = '|';
        reflashram[7] = hour / 10;
        reflashram[6] = hour % 10;
        reflashram[5] = '-';
        reflashram[4] = minute / 10;
        reflashram[3] = minute % 10;
        reflashram[2] = '-';
        reflashram[1] = second / 10;
        reflashram[0] = second % 10;
        iv18_reflash(reflashram);
        
        delay(2);
        
    }break;
    case (APPCPUSTATE) : {

        reflashram[8] = '|';
        reflashram[7] = 'C';
        reflashram[6] = 'P';
        reflashram[5] = 'U';
        reflashram[4] = '-';
        if((tempbai-48)==0)reflashram[3] = '|';
        else               reflashram[3] = tempbai-48;
        reflashram[2] = tempshi-48;
        reflashram[1] = tempge-48;
        reflashram[0] = '-';
        iv18_reflash(reflashram);
        delay(2);
        
        while (Serial.available() > 0)
        {
           for (int renum = 0; renum < 40; renum++)
           {
              comdata += char(Serial.read());
              delay(2);
              iv18_reflash(reflashram);
           }
        }
        if(comdata.length()>0)
        {
          tempge=int(comdata[1]);
          tempshi=int(comdata[0]);
          comdata="";
        }
        
    }break;
    case (APPGPUSTATE) : {

        reflashram[8] = '|';
        reflashram[7] = 'G';
        reflashram[6] = 'P';
        reflashram[5] = 'U';
        reflashram[4] = '-';
        if((tempbai-48)==0)reflashram[3] = '|';
        else               reflashram[3] = tempbai-48;
        reflashram[2] = tempshi-48;
        reflashram[1] = tempge-48;
        reflashram[0] = '-';
        iv18_reflash(reflashram);
        delay(2);
        
        while (Serial.available() > 0)
        {
           for (int renum = 0; renum < 40; renum++)
           {
              comdata += char(Serial.read());
              delay(2);
              iv18_reflash(reflashram);
           }
        }
        if(comdata.length()>0)
        {
          tempge=int(comdata[4]);
          tempshi=int(comdata[3]);
          comdata="";
        }

      } break;
  }

}
